package com.rpc.provider.service;

import com.rpc.api.bean.RpcRequest;
import com.rpc.api.bean.RpcResponse;

import java.io.*;
import java.lang.reflect.Method;
import java.net.Socket;

public class ProcessorHandler implements Runnable {

    private Socket socket;

    public ProcessorHandler(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        ObjectInputStream objectInputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {

            objectInputStream = new ObjectInputStream(socket.getInputStream());
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

            RpcRequest rpcRequest = (RpcRequest) objectInputStream.readObject();

            RpcResponse rpcResponse = invoke(rpcRequest);

            objectOutputStream.writeObject(rpcResponse);
            objectOutputStream.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (objectInputStream != null){
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (objectOutputStream != null){
                try {
                    objectOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private RpcResponse invoke(RpcRequest rpcRequest) {

        String clazzName = rpcRequest.getClazzName();
        String methodName = rpcRequest.getMethodName();
        Object[] valParams = rpcRequest.getValParams();
        Class<?>[] typeParams = new Class[valParams.length];

        for (int i=0; i<valParams.length; i++){
            typeParams[i] = valParams[i].getClass();
        }

        RpcResponse rpcResponse = new RpcResponse();

        try {
            // 获取实现类服务
            Object serviceImpl = RpcProxyServer.getInstance().getServiceImpl(clazzName);
            // 得到 需要执行的方法
            Method method = serviceImpl.getClass().getMethod(methodName, typeParams);
            // 反射调用目标方法
            Object result = method.invoke(serviceImpl, valParams);
            // 设置执行结果
            rpcResponse.setResult(result);

        } catch (Exception e) {
            e.printStackTrace();
            rpcResponse.setStatus(500);
            rpcResponse.setMsg(e.getMessage());
        }
        return rpcResponse;
    }
}
